package com.wanfeng.oa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.wanfeng.common.exception.WanfengException;
import com.wanfeng.model.system.SysMenu;
import com.wanfeng.model.system.SysRoleMenu;
import com.wanfeng.oa.mapper.SysMenuMapper;
import com.wanfeng.oa.mapper.SysRoleMenuMapper;
import com.wanfeng.oa.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wanfeng.oa.utils.MenuHelper;
import com.wanfeng.vo.system.AssginMenuVo;
import com.wanfeng.vo.system.MetaVo;
import com.wanfeng.vo.system.RouterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 *
 * 菜单表 服务实现类
 * </p>
 *
 * @author wanfeng
 * @since 2023-11-23
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Override
    public List<SysMenu> findNodes() {
        //查找到所有的数据
        List<SysMenu> sysMenuList = this.list(null);
        if (CollectionUtils.isEmpty(sysMenuList)) return null;

        //将这个数据传递给MenuBuilder构建树形结构
        List<SysMenu> list =MenuHelper.buildTrees(sysMenuList);
        return list;
    }

    @Override
    public void removeMenu(Long id) {
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getParentId,id);
        Integer integer = baseMapper.selectCount(queryWrapper);
        if(integer>0){
            throw new WanfengException(201,"该菜单有子菜单，不能删除");
        }
    }

    @Override
    public List<SysMenu> findSysMenuByRoleId(Long roleId) {
        //首先是status 菜单是否可用 1可用 0禁用
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getStatus,1);
        //所有的权限菜单
        List<SysMenu> allSysMenuList = baseMapper.selectList(queryWrapper);
        System.out.println("==============allSysMenuList================");
        System.out.println(allSysMenuList);
        System.out.println("==============allSysMenuList================");
        //这就是所有的list
        List<SysMenu> list=sysMenuMapper.findSysMenuByRoleId(roleId);
        //是否选中  private boolean isSelect;  这就是全部菜单和选中菜单的区别
        //有这个权限就是选中了
        List<Long> menuIdList = list.stream().map(e -> e.getId()).collect(Collectors.toList());
        allSysMenuList.forEach(permission -> {
            if (menuIdList.contains(permission.getId())) {
                permission.setSelect(true);
            } else {
                permission.setSelect(false);
            }
        });
        //封装成树形结构
        List<SysMenu> sysMenuList = MenuHelper.buildTrees(allSysMenuList);
        return sysMenuList;
    }

    //给角色分配权限
    @Transactional
    @Override
    public void doAssign(AssginMenuVo assignMenuVo) {
        Long roleId = assignMenuVo.getRoleId();
        List<Long> menuIdList = assignMenuVo.getMenuIdList();
        //先把之前的角色的角色删除，然后再添加
        sysRoleMenuMapper.update(null,new LambdaUpdateWrapper<SysRoleMenu>().set(SysRoleMenu::getIsDeleted,1).eq(SysRoleMenu::getRoleId,roleId));
        //批量添加
        sysRoleMenuMapper.batchAdds(roleId,menuIdList);
    }

    @Override
    public List<RouterVo> getRoutersByUserId(Long userId) {
        List<SysMenu> sysMenuList=new ArrayList<>();
        //1.admin为超级管理员，就获取所有菜单
        if(userId==1){
            //升序排列
            sysMenuList=this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getStatus,1).orderByAsc(SysMenu::getSortValue));
        }else{
            //根据id进行查找
            sysMenuList=sysMenuMapper.findUserMenuList(userId);
        }

        //构建成一棵树
        List<SysMenu> menuList = MenuHelper.buildTrees(sysMenuList);
        System.out.println("------------构建成的列表----------------");
        System.out.println(menuList);
        //转换成RouterVo
        List<RouterVo> routerVos=this.buildMenus(menuList);
        return routerVos;
    }

    //获取用户操作按钮的权限
    @Override
    public List<String> getButtonPerms(Long userId) {
        List<SysMenu> sysMenuList = null;
        //如果是超级管理员，查询所有权限
        if(userId.longValue()==1){
            LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysMenu::getStatus,1);
            sysMenuList=baseMapper.selectList(queryWrapper);
        }else{
            sysMenuList=sysMenuMapper.findUserMenuList(userId);
        }
        //直接使用stream流进行过滤就可以了
        //先过滤，然后map(可以返回不同的类型 in out)
        List<String> permsList = sysMenuList.stream().filter(item -> item.getType().intValue() == 2).map(item -> item.getPerms()).collect(Collectors.toList());
        return permsList;
    }


    /** //私有
     *  (0:目录,1:菜单,2:按钮)
     * @param menuList
     * @return
     * 还是递归操作
     */
    private  List<RouterVo> buildMenus(List<SysMenu> menuList) {
        ArrayList<RouterVo> routerVos = new ArrayList<>();
        for (SysMenu sysMenu : menuList) {
            RouterVo routerVo = new RouterVo();
            //路由地址
            routerVo.setPath(getRouterPath(sysMenu));
            routerVo.setHidden(false);
            routerVo.setComponent(sysMenu.getComponent());
            routerVo.setAlwaysShow(false);
            routerVo.setMeta(new MetaVo(sysMenu.getName(),sysMenu.getIcon()));
            //子路由
            List<SysMenu> children = sysMenu.getChildren();
            //隐藏路由
            //如果当前是菜单，需将按钮对应的路由加载出来，如：“角色授权”按钮对应的路由在“系统管理”下面
            if(sysMenu.getType().intValue()==1){
                //组件不为空的是隐藏路由
                List<SysMenu> hiddenMenuList = children.stream().filter(item -> !StringUtils.isEmpty(item)).collect(Collectors.toList());
                for (SysMenu menu : hiddenMenuList) {
                    RouterVo hiddenRouter=new RouterVo();
                    hiddenRouter.setPath(getRouterPath(menu));
                    hiddenRouter.setHidden(true);
                    hiddenRouter.setComponent(menu.getComponent());
                    hiddenRouter.setAlwaysShow(false);
                    hiddenRouter.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
                    routerVos.add(hiddenRouter);
                }
            }else{
                //type==0 目录  type=2 按钮
                //如果它的子菜单不为null,则进行递归
                //type=2的children为null
                //所以这是针对type=0(目录)的
                if(!CollectionUtils.isEmpty(children)){
                    if(children.size() > 0) {
                        routerVo.setAlwaysShow(true);
                    }
                    routerVo.setChildren(buildMenus(children));
                }
            }

            routerVos.add(routerVo);
        }
        return routerVos;
    }

    private  String  getRouterPath(SysMenu menu){
        String path="/"+menu.getPath();
        //如果为0 就是/system 目录
        if(menu.getType().intValue()!=0){
            path=menu.getPath();
        }
        return path;
    }


}
